package certificate


// 生成RSA密钥对
func generateRSAKeyPair(keySize int) (*rsa.PrivateKey, error) {
    // rand.Reader：加密安全的随机数生成器
    privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
    if err != nil {
        return nil, fmt.Errorf("生成RSA私钥失败：%v", err)
    }
    // 验证私钥（确保生成的私钥合法）
    if err := privateKey.Validate(); err != nil {
        return nil, fmt.Errorf("验证私钥失败：%v", err)
    }
    return privateKey, nil
}

// 加密保存私钥（AES-256-CBC）
func saveEncryptedPrivateKey(filename string, key *rsa.PrivateKey, password string) error {
    // 1. 生成加密密钥（基于密码的密钥派生，PBKDF2算法）
    salt := make([]byte, 8)
    if _, err := rand.Read(salt); err != nil {
        return fmt.Errorf("生成盐值失败：%v", err)
    }
    // 迭代10000次，生成32位AES密钥（256位）
    aesKey := pbkdf2.Key([]byte(password), salt, 10000, 32, sha1.New)

    // 2. 加密私钥内容（AES-CFB模式）
    privateKeyBytes := x509.MarshalPKCS1PrivateKey(key)
    block, err := aes.NewCipher(aesKey)
    if err != nil {
        return fmt.Errorf("创建AES加密器失败：%v", err)
    }
    iv := make([]byte, aes.BlockSize) // 初始化向量（16字节）
    if _, err := rand.Read(iv); err != nil {
        return fmt.Errorf("生成IV失败：%v", err)
    }
    cfb := cipher.NewCFBEncrypter(block, iv)
    encryptedBytes := make([]byte, len(privateKeyBytes))
    cfb.XORKeyStream(encryptedBytes, privateKeyBytes)

    // 3. 保存加密后的私钥（格式：salt + iv + 加密内容）
    file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
        return fmt.Errorf("创建加密私钥文件失败：%v", err)
    }
    defer file.Close()

    // 写入数据（salt:8字节 + iv:16字节 + 加密内容:剩余）
    if _, err := file.Write(append(append(salt, iv...), encryptedBytes...)); err != nil {
        return fmt.Errorf("写入加密私钥失败：%v", err)
    }
    return nil
}


// 生成RSA自签名证书
func generateSelfSignedCert(params CmdParams) error {
    // 1. 生成RSA密钥对
    privateKey, err := generateRSAKeyPair(params.KeySize)
    if err != nil {
        return err
    }
    publicKey := &privateKey.PublicKey

    // 2. 构建证书模板
    template, err := buildCertificateTemplate(params)
    if err != nil {
        return err
    }

    // 3. 生成自签名证书（参数：随机数、模板、签发者模板、公钥、私钥）
    certBytes, err := x509.CreateCertificate(rand.Reader, template, template, publicKey, privateKey)
    if err != nil {
        return fmt.Errorf("生成证书失败：%v", err)
    }

    // 4. 保存证书（PEM格式）
    if err := savePEMFile(params.OutCert, "CERTIFICATE", certBytes); err != nil {
        return err
    }

    // 5. 保存私钥（根据是否加密选择不同方式）
    if params.EncryptKey {
        if err := saveEncryptedPrivateKey(params.OutKey, privateKey, params.Password); err != nil {
            return err
        }
    } else {
        // 明文私钥（不推荐，仅测试用）
        privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
        if err := savePEMFile(params.OutKey, "RSA PRIVATE KEY", privateKeyBytes); err != nil {
            return err
        }
        // 设置私钥权限为600（仅所有者可读）
        if err := os.Chmod(params.OutKey, 0600); err != nil {
            return fmt.Errorf("设置私钥权限失败：%v", err)
        }
    }

    fmt.Printf("✅ 自签名证书生成成功！\n")
    fmt.Printf("📜 证书文件：%s\n", params.OutCert)
    fmt.Printf("🔑 私钥文件：%s\n", params.OutKey)
    if params.EncryptKey {
        fmt.Println("⚠️  私钥已加密，使用时需提供密码")
    }
    return nil
}
